import struct

class DataPakcet:
    __type = -1
    __data = bytearray()

    def __init__(self, type_: int, data: bytes):
        self.__type = type_
        self.__data = data

    def __str__(self) -> str:
        if self.__type == 0:
            return "DataPakcet(type={}, data={})".format(self.__type, self.__data)
        else:
            return "DataPakcet(type={}, message={})".format(self.__type, self.__data.decode())

    def getPacketType(self):
        return self.__type
    
    def getPacketData(self) -> bytes:
        return self.__data
    
    def getPacketDataWithDecode(self):
        if self.__type == 0:
            raise Exception("can't not decode binary bytes!")
        return self.__data.decode()
    
    def pack(self) -> bytes:
        return struct.pack("<B I {}s".format(len(self.__data)), self.__type, len(self.__data), len(self.__data))

class DataPacketQueue:
    __data = bytearray()

    def __init__(self) -> None:
        pass

    def post(self, data: bytes):
        self.__data += data
    
    def canGetPacket(self) -> bool:
        if len(self.__data) < 5:
            return False
        
        length = struct.unpack("<I", self.__data[1:5])[0]

        if len(self.__data) < length + 5:
            return False
        return True
    
    def getPacket(self) -> DataPakcet:
        if self.canGetPacket() == False:
            raise Exception("can't get a packet")

        length = struct.unpack("<I", self.__data[1:5])[0]
        t,_,data = struct.unpack("<B I {}s".format(length), self.__data[0: length + 5])
        self.__data = self.__data[length + 5:]
        return DataPakcet(t,data)